﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework.Input.Touch;

namespace TM.QWeibo.Client.UserControls
{
    public partial class MessageList : UserControl
    {
        public MessageList()
        {
            InitializeComponent();
            TouchPanel.EnabledGestures = GestureType.VerticalDrag;
        }

        #region 私有属性

        /// <summary>
        /// 是否正在拉取数据
        /// </summary>
        private bool isPolling { get; set; }
        /// <summary>
        /// 是否初始化，加载数据
        /// </summary>
        private bool isInited { get; set; }

        /// <summary>
        /// 加载数据的类型
        /// </summary>
        private EPollType pollType { get; set; }

        /// <summary>
        /// 最后一条微博的时间戳
        /// </summary>
        private long lastTimestamp { get; set; }
        /// <summary>
        /// 第一条微博的时间戳
        /// </summary>
        private long firstTimestamp { get; set; }

        /// <summary>
        /// 拉取数据类型
        /// </summary>
        private enum EPollType
        {
            /// <summary>
            /// 默认，结果绑定到控件
            /// </summary>
            Default,
            /// <summary>
            /// 下一页，结果追加到末尾
            /// </summary>
            NextPage,
            /// <summary>
            /// 最新，结果插到开头
            /// </summary>
            Lastest
        }


        #endregion

        #region 本控件事件

        private Action beforeLoadingCallback { get; set; }

        private Action<object> afterLoadedCallback { get; set; }

        /// <summary>
        /// 选择微博
        /// </summary>
        public Action<SDK.Objects.Tweet> Selected { get; set; }

        /// <summary>
        /// 获取最新之后的回调
        /// </summary>
        public Action GotLastest { get; set; }

        #endregion

        #region 事件
        private void DataListBox_Tap(object sender, GestureEventArgs e)
        {
            if (Selected != null)
            {
                Selected((SDK.Objects.Tweet)DataListBox.SelectedItem);
            }
        }

        /// <summary>
        /// 手势是否是垂直拖拽
        /// </summary>
        private bool isVerticalDrag { get; set; }

        private void GestureListener_GestureCompleted(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            if (isVerticalDrag || AppSetting.HightDragSensitivity)
            {
                var scrollviewer = AppSetting.FindChildOfType<ScrollViewer>(DataListBox);
                if (scrollviewer == null)
                {
                    return;
                }
                //到底部
                if (Math.Abs(scrollviewer.VerticalOffset - scrollviewer.ScrollableHeight) < 2)
                {
                    GetNextPage();
                }
                //顶部
                else if (scrollviewer.VerticalOffset < 0.000001)
                {
                    GetLastest();
                }
            }
        }

        private void GestureListener_GestureBegin(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gs = TouchPanel.ReadGesture();
                if (gs.GestureType == GestureType.VerticalDrag)
                {
                    isVerticalDrag = true;
                }
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 初始化控件，首页和提及调用此方法
        /// </summary>
        /// <param name="beforeLoading"></param>
        /// <param name="afterCallback"></param>
        public void Init(Action beforeLoading = null, Action<object> afterCallback = null)
        {

            if (isInited)
            {
                return;
            }

            if (beforeLoading != null)
            {
                beforeLoadingCallback = beforeLoading;
                beforeLoading();
            }

            if (afterCallback != null)
            {
                afterLoadedCallback = afterCallback;
            }

            pollType = EPollType.Default;

            isPolling = true;

            Dal.Message.Instance.Inbox(SDK.Objects.PageFlag.First, 0, GetDataEnd);

        }

        /// <summary>
        /// 重置
        /// </summary>
        public void Reset()
        {

            isInited = false;

            pollType = EPollType.Default;

            Init(beforeLoadingCallback, afterLoadedCallback);

        }

        #endregion

        #region 私有方法

        private void GetDataEnd(ICollection<SDK.Objects.Tweet> messages) {

            isPolling = false;

            isVerticalDrag = false;

            Dispatcher.BeginInvoke(() =>
            {
                var data = (IEnumerable<SDK.Objects.Tweet>)DataListBox.ItemsSource;

                if (pollType == EPollType.NextPage)
                {
                    data = data.Concat(messages).ToList();
                }
                else if (pollType == EPollType.Lastest)
                {
                    messages = messages.Where(t => t.Timestamp > firstTimestamp).ToList();
                    if (messages.Count > 0)
                    {
                        data = messages.Concat(data).ToList();
                    }
                }
                else
                {
                    if (messages != null && messages.Count > 0)
                    {
                        isInited = true;
                    }
                    data = messages;
                }

                if (data != null && data.Count() > 0)
                {
                    lastTimestamp = data.LastOrDefault().Timestamp;

                    firstTimestamp = data.FirstOrDefault().Timestamp;

                    data = data.Distinct(new MessageCompare()).ToList();
                }

                //处理界面提示

                DataListBox.ItemsSource = data;

                DataListBox.UpdateLayout();

                DataListBox.ShowListFooter = false;

                DataListBox.ShowListHeader = false;

                if (afterLoadedCallback != null)
                {
                    afterLoadedCallback(messages);
                }

                if ((pollType == EPollType.Lastest || pollType == EPollType.Default) && GotLastest != null)
                {
                    GotLastest();
                }
            });

        }

        /// <summary>
        /// 下一页
        /// </summary>
        private void GetNextPage()
        {

            if (!this.IsCanPollData()) return;

            if (beforeLoadingCallback != null)
            {
                beforeLoadingCallback();
            }

            isPolling = true;

            pollType = EPollType.NextPage;

            Dal.Message.Instance.Inbox(SDK.Objects.PageFlag.Down, lastTimestamp, GetDataEnd);

            Dispatcher.BeginInvoke(() =>
            {
                if (!DataListBox.ShowListFooter)
                {
                    DataListBox.ShowListFooter = true;
                    DataListBox.ScrollTo(DataListBox.ListFooter);
                }
            });
        
        }

        /// <summary>
        /// 获取最新
        /// </summary>
        private void GetLastest()
        {

            if (!this.IsCanPollData()) return;

            if (beforeLoadingCallback != null)
            {
                beforeLoadingCallback();
            }

            isPolling = true;

            pollType = EPollType.Lastest;

            Dal.Message.Instance.Inbox(SDK.Objects.PageFlag.First, firstTimestamp, GetDataEnd);

            Dispatcher.BeginInvoke(() =>
            {
                if (!DataListBox.ShowListHeader)
                {
                    DataListBox.ShowListHeader = true;
                }
            });
        }

        /// <summary>
        /// 可以请求拉取数据
        /// </summary>
        /// <returns></returns>
        private bool IsCanPollData()
        {
            return !isPolling;
        }

        /// <summary>
        /// 去重对比
        /// </summary>
        public class MessageCompare : IEqualityComparer<SDK.Objects.Tweet> {

            public bool Equals(SDK.Objects.Tweet x, SDK.Objects.Tweet y)
            {
                if (x == null && y == null)
                {
                    return false;
                }
                else
                {
                    return string.Compare(x.Name,y.Name)==0;
                }
            }

            public int GetHashCode(SDK.Objects.Tweet obj)
            {
                return 0;
            }
        }

        #endregion
    }
}
